#include <iostream>
#include <string>
#include <list>
#include <iostream>
#include "Robots.h"

using namespace std;

Robots::Robots(std::string str) {
	try{
	
	naoPossoNada = false;
	if (str == "")
		return;
	
	for (uint i = 0; i < str.size(); i++)
		str[i] = tolower(str[i]);
	
	uint userAgentIndex = str.find("user-agent: *");
	if (userAgentIndex != string::npos) {
		//limitar a faixa de interesse
		str = str.substr(userAgentIndex, str.size());
		uint outOfScopeIndex = str.substr(1,str.size()).find("user-agent");
		if (outOfScopeIndex != string::npos)
			str = str.substr(0, outOfScopeIndex);
		outOfScopeIndex = str.find("\n\n");
		if (outOfScopeIndex != string::npos)
			str = str.substr(0, outOfScopeIndex);
		
		//adiciona \n ao final, caso nao exista
		if (str[str.size()-1] == '\n')
			str += "\n";
		
		//encontra os diretorios proibidos
		uint disallowIndex= 0;
		string dir;
		
		while ((disallowIndex = str.find("disallow:")) != string::npos) {
			str = str.substr(disallowIndex+9, str.size());
			dir = str.substr(0, str.find('\n'));
			trim(dir);
			//Se tiver vazio, ou espacos no meio, vou procurar proximo disallow:
			if (dir == "" || dir.find(" ") != string::npos || dir.find("\t") != string::npos)
				continue;
			
			//retira a barra no comeco, caso exista
			if (dir[0] == '/')
				dir.erase(0,1);
			
			//remove barra no final, caso exista
			if (dir[dir.size()-1] == '/')
				dir.erase(dir.size()-1);
			
			if (dir == "" || (dir.rfind('*') != string::npos && dir.rfind('*') != 0)) {
				naoPossoNada = true;
				break;
			}
				
			
			//se comeca com '*', insere em lista especial
			if (dir[0] == '*') {
				dir.erase(0,1);
				asteriskFolders.push_back(dir);
			}
			else
				disallowedFolders.push_back(dir);
		}
	}
	
	}catch(...){
		cout << "Baggio de novo, agora no Robots ... " << endl;
	}
}

void Robots::trim(string &str) {
	try{
	string forbidden = " \t\r";
	while (str.find_last_of(forbidden) == str.size()-1 && str.size() > 0) {
		str.erase(str.size()-1);
	}
	while (str.find_first_of(forbidden) == 0 && str.size() > 0) {
		str.erase(0,1);
	}
	}catch(...){
		cout << "Baggio de novo, agora no Robots ... " << endl;
	}
}

bool Robots::isAllowed(string str) {
	try{
	if (naoPossoNada)
		return false;
	list<string>::iterator it;
	for (it = disallowedFolders.begin(); it != disallowedFolders.end(); it++) {
		if (str.find(*it) == 0 )
		{
			if (str == (*it))
				return false;
			else if (str[it->size()] == '/')
				return false;
		}
	}
	string auxStr = "";
	int index = 0;
	for (it = asteriskFolders.begin(); it != asteriskFolders.end(); it++) {
		if ((index = str.find(*it)) != string::npos )
		{
			auxStr = str.substr(index, str.size()); 
			if (auxStr == (*it))
				return false;
			else if (auxStr[it->size()] == '/')
				return false;
		}
	}
	return true;
	}catch(...){
		cout << "Baggio de novo, agora no Robots ... " << endl;
		return false;
	}
}

